package org.eiahe.hr.performance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ehe.common.core.exception.ServiceException;
import org.ehe.common.core.utils.MapstructUtils;
import org.eiahe.hr.performance.domain.PerformanceScorer;
import org.eiahe.hr.performance.domain.bo.PerformanceScorerBo;
import org.eiahe.hr.performance.domain.vo.PerformanceScorerVo;
import org.eiahe.hr.filler.EmployeeNameFiller;
import org.eiahe.hr.performance.mapper.PerformanceScorerMapper;
import org.eiahe.hr.performance.service.IPerformanceScorerService;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;

/**
 * 评分人设置Service业务层处理
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@Service
public class PerformanceScorerServiceImpl implements IPerformanceScorerService {

    private final PerformanceScorerMapper baseMapper;
    private final EmployeeNameFiller employeeNameFiller;

    @Override
    public PerformanceScorerVo queryById(Long id) {
        PerformanceScorerVo performanceScorerVo = baseMapper.selectVoById(id);
        employeeNameFiller.fillEmployeeName(performanceScorerVo,
            PerformanceScorerVo::getEmployeeNo,
            PerformanceScorerVo::setEmployeeName);
        return performanceScorerVo;
    }


    @Override
    public TableDataInfo<PerformanceScorerVo> queryPageListVo(PerformanceScorerBo scorer, PageQuery pageQuery) {
        LambdaQueryWrapper<PerformanceScorer> lqw = buildQueryWrapper(scorer);
        Page<PerformanceScorerVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
        employeeNameFiller.fillEmployeeNames(page.getRecords(),
            PerformanceScorerVo::getEmployeeNo,
            PerformanceScorerVo::setEmployeeName);

        return TableDataInfo.build(page);
    }

    private LambdaQueryWrapper<PerformanceScorer> buildQueryWrapper(PerformanceScorerBo scorer) {
        LambdaQueryWrapper<PerformanceScorer> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(scorer.getEmployeeNo()), PerformanceScorer::getEmployeeNo, scorer.getEmployeeNo());
        lqw.eq(StringUtils.isNotBlank(scorer.getScorerNo()), PerformanceScorer::getScorerNo, scorer.getScorerNo());
        lqw.eq(StringUtils.isNotBlank(scorer.getScoreType()), PerformanceScorer::getScoreType, scorer.getScoreType());
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(PerformanceScorerBo bo) {
        validateScorerWeight(bo.getEmployeeNo(), bo.getWeight(), null);
        PerformanceScorer scorer = MapstructUtils.convert(bo, PerformanceScorer.class);
        return baseMapper.insert(scorer) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(PerformanceScorerBo bo) {
        validateScorerWeight(bo.getEmployeeNo(), bo.getWeight(), null);
        PerformanceScorer scorer = MapstructUtils.convert(bo, PerformanceScorer.class);
        return baseMapper.updateById(scorer) > 0;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        if (isValid) {
            // 校验逻辑可以根据需要添加
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 校验员工评分人权重总和
     */
    private void validateScorerWeight(String employeeNo, BigDecimal newWeight, Long excludeId) {
        LambdaQueryWrapper<PerformanceScorer> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceScorer::getEmployeeNo, employeeNo);
        lqw.eq(PerformanceScorer::getDelFlag, "0");
        if (excludeId != null) {
            lqw.ne(PerformanceScorer::getId, excludeId);
        }

        List<PerformanceScorer> list = baseMapper.selectList(lqw);
        BigDecimal totalWeight = list.stream()
            .map(PerformanceScorer::getWeight)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        totalWeight = totalWeight.add(newWeight);

        if (totalWeight.compareTo(new BigDecimal("100")) > 0) {
            throw new ServiceException("评分人权重总和不能超过100%，当前已分配：" + totalWeight);
        }
    }
}
